Quarto extensions

last modified

2024–10–29

Installation of extensions

Quarto extensions can be installed with quarto add from a source, i.e.

  • a GitHub repository,<account>/<repository> optionally with appended reference to a @tag,
  • a GitHub repository subdirectory,<account>/<repository>/<directory>,
  • an online zip or tar.gz file https://<host>/<path>/<file>,
  • a local zip or tar.gz file/<path>/<file>, or
  • a local directory /<path>/<directory>.

The source must immediately contain a subdirectory _extensions. Its contents are copied into a subdirectory _extensions of the project root.

quarto use template operates similary, but copies all contents of the source, including an optional _extensions subdirectory. This can be used to initialize a project with documentation or example files in the source root (README.md, example.qmd, template.qmd, etc.)

Extensions by type

Several extensions of the same or different type can be defined under the same or different extension name in the same source. However, different extensions from the same source cannot be installed separately.

Type “filter”

── _extensions
   └── <name>
       ├── _extension.yml
       └── <script>.lua
── README.md
── example.qmd

_extension.yml contains:

contributes:
  filters:
    - <script>.lua

A filter is implemented by a Lua script <script>.lua:

function Header(el)
  el.content = pandoc.Emph(el.content)
  return el
end

The filters key can list more than one script, in which case all of them are executed in sequence.

A filter extension is used with

filters:
  - <name>

in the document metadata. By default, user filters are run before Quarto’s built-in filters, but that can be changed by explicitly including quarto in the list of filters.

Type “shortcode”

── _extensions
   └── <name>
       ├── _extension.yml
       └── <script>.lua
── README.md
── example.qmd

_extension.yml contains:

contributes:
  shortcodes:
    - <script>.lua

A shortcode is implemented by a Lua script <script>.lua:

return {
  ['<code>'] = function(args, kwargs, meta) 
    return pandoc.Str("Hello!")
  end
}

It can have arguments and has access to the document metadata. A shortcode extension can define multiple shortcodes in multiple script files.

A shortcode is used with {{< <code> <arguments> >}} in document code.

Type “custom format”

A custom format is based on one of Quarto’s base formats, html, pdf, docx, revealjs, and typst. We here illustrate a customization of html.

── _extensions
   └── <name>
       ├── _extension.yml
       └── custom.scss
── README.md
── template.qmd

There can be additional files used by the format alongside _extension.yml, like here custom.scss.

_extension.yml contains for example:

contributes:
  formats:
    html:
      theme: [yeti, custom.scss]

The custom format is used with

format: <name>-html

in the document metadata, i.e. a custom format is identified by <name>-<base format>.

Custom formats based on other formats work the same way, e.g. a custom pdf format could specify include-in-header: header.tex in _extension.yml and include header.tex alongside it, or a custom docx format could specify reference-doc: reference.docx in _extension.yml and include reference.docx. A custom format can also specify template-partials.

An extension can define several custom formats with the same <name> but different base formats, in which case options common to all custom formats can be specified under the “format” common.

Type “journal format”

Journal formats are just custom formats used to prepare a manuscript for submission to a journal. The mechanics and feature set are the same. The Quarto documentation includes special guidance for preparing journal formats, a detailed template, and a repository of ready formats for some publishers.

Type “revealjs plugin”

── _extensions
   └── <name>
       ├── _extension.yml
       ├── <style>.css
       └── <script>.js
── README.md
── example.qmd

_extension.yml contains:

contributes:
  revealjs-plugins:
    - name: Reveal<Name>
      script:
        - <script>.js
      stylesheet:
        - <style>.css

Here <Name> is a capitalized version of <name>, from which dashes and spaces have been removed.

The plugin is used with

revealjs-plugins:
  - <name>

in the document metadata.

A reveal.js plugin inserts scripts and style sheets into a presentation; functionality is implemented using the reveal.js API.

Type “metadata”

── _extensions
   └── <name>
       └── _extension.yml
── README.md

_extension.yml contains:

contributes:
  metadata:
    project:
      ...

In theory, this should treat settings under project: in _extension.yml as if they were under project: in _quarto.yml. In practice, it seems to be currently limited to specifying pre- and post-render scripts.